﻿using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Web.Mvc;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace BrettM.Web.Restful
{


    public class ModelFilterAttribute
           : ActionFilterAttribute
    {

        public ModelFilterAttribute(Type[] dataTypes, string key)
        {
            DataType = dataTypes;
            Key = key;
        }

        public ModelFilterAttribute(Type dataType, string key)
        {
            DataType = new Type[] { dataType };
            Key = key;
        }

        public Type[] DataType { get; private set; }
        public string Key { get; private set; }


        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if ((filterContext.HttpContext.Request.Headers["Content-Type"] ?? string.Empty).Contains("application/json"))
            {
                foreach (var type in DataType)
                {
                    try
                    {
                        var o = new DataContractJsonSerializer(type)
                                            .ReadObject(filterContext.HttpContext.Request.InputStream);
                        filterContext.ActionParameters[this.Key] = o;
                        return;
                    }
                    finally { }

                }
            }
            else
            {
                var xmlRoot =
                    XElement.Load(new StreamReader(filterContext.HttpContext.Request.InputStream,
                                                  filterContext.HttpContext.Request.ContentEncoding));
                foreach (var type in DataType)
                {
                    try
                    {
                        var o = new XmlSerializer(type).Deserialize(xmlRoot.CreateReader());
                        filterContext.ActionParameters[this.Key] = o;
                        return;
                    }
                    catch
                    {
                        continue;
                    }
                }


            }
        }
    }
}
